﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using System.Threading.Tasks;

namespace FrogEngine
{
	public class MouseInputService : GameEntityServiceBase<IHandlesMouseInput>, IMouseInputService
	{
		public MouseInputService(IEngine engine)
			: base(engine)
		{
			serviceOrder = 1;
		}

		private MouseState currentState;
		public MouseState CurrentState
		{
			get { return currentState; }
		}

		private MouseState previousState;
		public MouseState PreviousState
		{
			get { return previousState; }
		}

		public override bool Subscribe(IGameEntity entity)
		{
			if (base.Subscribe(entity))
				return true;
			else
				throw new EntityCompatibilityException(entity.GetType(), this.GetType());
		}

		public bool Unsubscribe(IGameEntity entity)
		{
			return base.Unsubscribe(entity);
		}

		public void Update(GameTime gameTime)
		{
			currentState = Mouse.GetState();

			if (isPaused)
				return;
#if WINDOWS
			int cx = this.Engine.Window.ClientBounds.Width / 2;
			int cy = this.Engine.Window.ClientBounds.Height / 2;
			float dx = 0, dy = 0;
			if (currentState.X != cx)
			{
				dx = (currentState.X - cx);
			}
			if (currentState.Y != cy)
			{
				dy = (currentState.Y - cy);
			}

			Mouse.SetPosition(cx, cy);
#endif
#if WINDOWS
			Parallel.ForEach(subscribedEntities.Cast<IHandlesMouseInput>(), new Action<IHandlesMouseInput>(a => a.HandleInput(gameTime, CurrentState, PreviousState, dx, dy)));
#else
			foreach (var entity in subscribedEntities.Cast<IHandlesMouseInput>())
				entity.HandleInput(gameTime, CurrentState, PreviousState);
#endif
			previousState = currentState;
		}

		private bool isPaused = false;
		public void Pause()
		{
			isPaused = true;
		}

		public void Resume()
		{
			isPaused = false;
		}
	}
}
